import java.util.*;
import java.io.*;

public class test{
    static final double INF = Double.MAX_VALUE;
    static double[] dis; // 存储从起点到各魔法阵的"最短路径"值
    static boolean[] vis; // 标记是否已访问
    static List<double[]>[] adj; // 邻接表

    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(in.readLine());
        double[][] circles = new double[n+1][3]; // circles[1..n][x,y,r]

        // 读取输入
        for (int i = 1; i <= n; i++) {
            String[] parts = in.readLine().split(" ");
            circles[i][0] = Double.parseDouble(parts[0]);
            circles[i][1] = Double.parseDouble(parts[1]);
            circles[i][2] = Double.parseDouble(parts[2]);
        }

        // 初始化
        dis = new double[n+1];
        vis = new boolean[n+1];
        adj = new ArrayList[n+1];
        for (int i = 1; i <= n; i++) {
            adj[i] = new ArrayList<>();
        }

        // 构建邻接表
        for (int i = 1; i <= n; i++) {
            for (int j = i+1; j <= n; j++) {
                double dx = circles[i][0] - circles[j][0];
                double dy = circles[i][1] - circles[j][1];
                double distance = Math.sqrt(dx*dx + dy*dy);
                double rSum = circles[i][2] + circles[j][2];
                double cost = (distance <= rSum) ? 0 : distance - rSum;

                // 无向图，双向添加
                adj[i].add(new double[]{j, cost});
                adj[j].add(new double[]{i, cost});
            }
        }
        double min = 0x3f3f3f3f;
        out:for(int j = 1;j <= n;j++){
            dijkstra(j);
            double total = 0;
            for (int i = 1; i <= n; i++) {
                if (dis[i] != INF) {
                    total += dis[i];
                }else {
                    continue out;
                }
            }
            min = Math.min(total,min);
        }
        System.out.printf("%.2f\n", min);
    }

    static void dijkstra(int a) {
        Arrays.fill(dis, INF);
        dis[a] = 0; // 从第一个魔法阵开始

        PriorityQueue<double[]> pq = new PriorityQueue<>(Comparator.comparingDouble(h -> h[1]));
        pq.offer(new double[]{a, 0});

        while (!pq.isEmpty()) {
            double[] curr = pq.poll();
            int u = (int)curr[0];

            if (vis[u]) continue;
            vis[u] = true;

            for (double[] edge : adj[u]) {
                int v = (int)edge[0];
                double w = edge[1];

                if (dis[v] > dis[u] + w) {
                    dis[v] = dis[u] + w;
                    pq.offer(new double[]{v, dis[v]});
                }
            }
        }
    }
}